#include "StdAfx.h"
#include "AIFlyingVehicle.h"

CAIFlyingVehicle::CAIFlyingVehicle()
{}


CAIFlyingVehicle::~CAIFlyingVehicle()
{
  SetObservable(false);
  SetObserver(false);
}


void CAIFlyingVehicle::SetObserver(bool observer)
{
  if (m_observer != observer)
  {
    if (observer)
    {
      ObserverParams observerParams;
      observerParams.entityID = GetEntityID();
      observerParams.factionMask = GetFactionVisionMask(GetFactionID());
      observerParams.typeMask = GetObserverTypeMask();
      observerParams.eyePos = GetPos();
      observerParams.eyeDir = GetViewDir();
      observerParams.priority = eMediumPriority;
      observerParams.sightRange = m_Parameters.m_PerceptionParams.sightRange;
      observerParams.callback = functor(CAIFlyingVehicle::OnVisionChanged);

      PhysSkipList skipList;
      GetPhysicalSkipEntities(skipList);

      observerParams.skipListSize = std::min<size_t>(skipList.size(), ObserverParams::MaxSkipListSize);
      for (size_t i = 0; i < static_cast<size_t>(observerParams.skipListSize); ++i)
        observerParams.skipList[i] = skipList[i];

      GetSightFOVCos(observerParams.primaryFoVCos, observerParams.peripheralFoVCos);

      VisionID visionID = GetVisionID();
      if (!visionID)
      {
        visionID = gAIEnv.pVisionMap->CreateVisionID(GetName());

        SetVisionID(visionID);
      }

      gAIEnv.pVisionMap->RegisterObserver(visionID, observerParams);
    }
    else
    {
      if (VisionID visionID = GetVisionID())
        gAIEnv.pVisionMap->UnregisterObserver(visionID);
    }

    m_observer = observer;
  }
}

//This is a "hot-fix". Need to dig out the real issue
void  CAIFlyingVehicle::Reset(EObjectResetType type)
{
  if (AIOBJRESET_INIT == type)
  {
    if (IEntity *entity = GetEntity())
    {
      if (IEntityProxy *proxy = entity->GetProxy(ENTITY_PROXY_SCRIPT))
      {
        SEntitySpawnParams params;
        proxy->Reload(entity, params);
      }
    }
  }

  Base::Reset(type);
}


void CAIFlyingVehicle::OnVisionChanged(const VisionID& observerID, const ObserverParams& observerParams, const VisionID& observableID, const ObservableParams& observableParams, bool visible)
{
  const ObserverParams *params = gAIEnv.pVisionMap->GetObserverParams(observerID);

  if (params)
  {
    IEntity *ent = gEnv->pEntitySystem->GetEntity(params->entityID);
    IAIObject *obj = ent->GetAI();

    if (obj)
    {
      if (CPuppet *puppet = obj->CastToCPuppet())
      {
        CAIFlyingVehicle *flyingAI = static_cast<CAIFlyingVehicle*>(puppet);

        const EntityId targetID = observableParams.entityID;
        if (targetID != flyingAI->GetEntityID())
        {
          if (visible)
          {
            if (targetID)
            {
              bool projectile = false;

              if (IEntity* entity = gEnv->pEntitySystem->GetEntity(observableParams.entityID))
              {
                if (IAIObject* aiObject = entity->GetAI())
                {
                  uint16 aiObjectType = static_cast<CAIObject*>(aiObject)->GetType();
                  if ((aiObjectType == AIOBJECT_GRENADE) || (aiObjectType == AIOBJECT_RPG))
                  {
                    const Vec3 &pos = entity->GetPos();
                    const Vec3 &ownPos = flyingAI->GetPos();
                    Vec3 diff = ownPos-pos;
                    diff.Normalize();

                    pe_status_dynamics dynamics;
                    if (entity->GetPhysics())
                    {
                      entity->GetPhysics()->GetStatus(&dynamics);

                      if (dynamics.v.dot(diff) > 0.9f)
                      {
                        GoalParams param;
                        param.SetName("params");

                        GoalParams paramChild;
                        paramChild.SetName("impulse");
                        paramChild.SetValue(pos);

                        GoalParams paramChild2;
                        paramChild2.SetName("dir");
                        paramChild2.SetValue(dynamics.v);
                        paramChild.AddChild(paramChild2);

                        GoalParams paramChild3;
                        paramChild3.SetName("id");
                        paramChild3.SetValue(observableParams.entityID);
                        paramChild.AddChild(paramChild3);

                        param.AddChild(paramChild); 


                        CGoalPipe *pipe = flyingAI->GetCurrentGoalPipe();
                        if(pipe)
                        {
                          pipe->ParseParams(param);
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
